
#include <cstdio>
#include <cstring>
#include "parser.h"
#include "vm.h"
#include "core.h"

#define MAX_LINE_LEN 1024

// ---TokenList---
const char *tokenArray[] = {
        "UNKNOWN",
        "NUM",
        "STRING",
        "ID",
        "INTERPOLATION",
        "VAR",
        "FUN",
        "IF",
        "ELSE",
        "TRUE",
        "FALSE",
        "WHILE",
        "FOR",
        "BREAK",
        "CONTINUE",
        "RETURN",
        "NULL",
        "CLASS",
        "THIS",
        "STATIC",
        "IS",
        "SUPER",
        "IMPORT",
        "COMMA",
        "COLON",
        "LEFT_PAREN",
        "RIGHT_PAREN",
        "LEFT_BRACKET",
        "RIGHT_BRACKET",
        "LEFT_BRACE",
        "RIGHT_BRACE",
        "DOT",
        "DOT_DOT",
        "ADD",
        "SUB",
        "MUL",
        "DIV",
        "MOD",
        "ASSIGN",
        "BIT_AND",
        "BIT_OR",
        "BIT_NOT",
        "BIT_SHIFT_RIGHT",
        "BIT_SHIFT_LEFT",
        "LOGIC_AND",
        "LOGIC_OR",
        "LOGIC_NOT",
        "EQUAL",
        "NOT_EQUAL",
        "GREATE",
        "GREATE_EQUAL",
        "LESS",
        "LESS_EQUAL",
        "QUESTION",
        "EOF"
};
// ---------------

//运行命令行,输出Token数据
static void RunCli_Token() {

    char sourceLine[MAX_LINE_LEN];
    printf("VanTideL Version: 0.1\n");
    VM *vm = new VM();

    while (true) {
        printf(">>> ");

        //若读取失败或者键入quit就退出循环
        if (!fgets(sourceLine, MAX_LINE_LEN, stdin) ||
            memcmp(sourceLine, "quit", 4) == 0) {
            break;
        }
        Parser parser = Parser(vm, nullptr, sourceLine, nullptr);
        while (parser.curToken.type != TOKEN_EOF) {
            Parser::GetNextToken(&parser);
            printf("%dL-Token[%d]: %s [", parser.curToken.lineNo, parser.curToken.type,
                   tokenArray[parser.curToken.type]);
            for (uint32_t index = 0; index < parser.curToken.length; index++) {
                printf("%c", *(parser.curToken.start + index));
            }
            printf("]\r\n");
        }
    }
}

//执行脚本文件,输出Token数据
static void RunFile_Token(const char *path) {
    const char *lastSlash = strrchr(path, '/');

    if (lastSlash != nullptr) {
        char *root = (char *) malloc(lastSlash - path + 2);
        memcpy(root, path, lastSlash - path + 1);
        root[lastSlash - path + 1] = '\0';
        rootDir = root;
    }

    VM *vm = new VM();
    const char *sourceCode = ReadFile(path);

    Parser parser = Parser(vm, path, sourceCode, nullptr);

    while (parser.curToken.type != TOKEN_EOF) {
        Parser::GetNextToken(&parser);
        printf("%dL-Token[%d]: %s [", parser.curToken.lineNo, parser.curToken.type,
               tokenArray[parser.curToken.type]);
        for (uint32_t index = 0; index < parser.curToken.length; index++) {
            printf("%c", *(parser.curToken.start + index));
        }
        printf("]\r\n");
    }
}

int main(int argc, const char *argv[]) {
    if (argc == 1) {
        RunCli_Token();
    } else {
        RunFile_Token(argv[1]);
    }
    return 0;
}
